package com.jrabbits.api.sys.utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.jrabbits.api.sys.entity.Area;
import com.jrabbits.api.sys.entity.Menu;
import com.jrabbits.api.sys.entity.Office;
import com.jrabbits.api.sys.entity.Role;
import com.jrabbits.api.sys.entity.User;
import com.jrabbits.api.sys.service.AreaService;
import com.jrabbits.api.sys.service.CurrentUserSevice;
import com.jrabbits.api.sys.service.MenuService;
import com.jrabbits.api.sys.service.OfficeService;
import com.jrabbits.api.sys.service.RoleService;
import com.jrabbits.api.sys.service.SystemService;
import com.jrabbits.api.sys.service.UserService;
import com.jrabbits.common.constant.CacheDict;
import com.jrabbits.common.filter.DataScopeFilter;
import com.jrabbits.common.utils.CacheUtils;
import com.jrabbits.common.utils.SpringContextHolder;


	/**
	 * 用户工具类
	 * @author jrabbits
	 * @version 2013-12-05
	 */
	public class UserUtils {

		
		
		/*private static SystemCache systemCache = SpringContextHolder.getBean(SystemCache.class);*/
		
		private static AreaService areaService = SpringContextHolder.getBean(AreaService.class);
		
		private static OfficeService officeService = SpringContextHolder.getBean(OfficeService.class);
		
		private static RoleService roleService = SpringContextHolder.getBean(RoleService.class);
		
		private static UserService userService = SpringContextHolder.getBean(UserService.class);
		
		private static MenuService menuService = SpringContextHolder.getBean(MenuService.class);
		
		private static CurrentUserSevice currentUserSevice = SpringContextHolder.getBean(CurrentUserSevice.class);;
		
		/**
		 * 根据ID获取用户
		 * @param id
		 * @return 取不到返回null
		 */
		public static User get(String id){
			User user = (User)CacheUtils.get(CacheDict.USER_CACHE, CacheDict.USER_CACHE_ID_ + id);
			if (user ==  null){
				user = userService.get(id);
				if (user == null){
					return null;
				}
				user.setRoleList(roleService.findList(new Role(user)));
				CacheUtils.put(CacheDict.USER_CACHE, CacheDict.USER_CACHE_ID_ + user.getId(), user);
				CacheUtils.put(CacheDict.USER_CACHE, CacheDict.USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
			}
			return user;
		}
		
		/**
		 * 根据登录名获取用户
		 * @param loginName
		 * @return 取不到返回null
		 */
		public static User getByLoginName(String loginName){
			User user = (User)CacheUtils.get(CacheDict.USER_CACHE, CacheDict.USER_CACHE_LOGIN_NAME_ + loginName);
			if (user == null){
				user = userService.getByLoginName(new User(null, loginName));
				if (user == null){
					return null;
				}
				user.setRoleList(roleService.findList(new Role(user)));
				CacheUtils.put(CacheDict.USER_CACHE, CacheDict.USER_CACHE_ID_ + user.getId(), user);
				CacheUtils.put(CacheDict.USER_CACHE, CacheDict.USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
			}
			return user;
		}
		
		/**
		 * 清除当前用户缓存
		 */
		public static void clearCache(){
			removeCache(CacheDict.CACHE_AUTH_INFO);
			removeCache(CacheDict.CACHE_ROLE_LIST);
			removeCache(CacheDict.CACHE_MENU_LIST);
			removeCache(CacheDict.CACHE_AREA_LIST);
			removeCache(CacheDict.CACHE_OFFICE_LIST);
			removeCache(CacheDict.CACHE_OFFICE_ALL_LIST);
			UserUtils.clearCache(getUser());
		}
		
		/**
		 * 清除指定用户缓存
		 * @param user
		 */
		public static void clearCache(User user){
			CacheUtils.remove(CacheDict.USER_CACHE, CacheDict.USER_CACHE_ID_ + user.getId());
			CacheUtils.remove(CacheDict.USER_CACHE, CacheDict.USER_CACHE_LOGIN_NAME_ + user.getLoginName());
			CacheUtils.remove(CacheDict.USER_CACHE, CacheDict.USER_CACHE_LOGIN_NAME_ + user.getOldLoginName());
			if (user.getOffice() != null && user.getOffice().getId() != null){
				CacheUtils.remove(CacheDict.USER_CACHE, CacheDict.USER_CACHE_LIST_BY_OFFICE_ID_ + user.getOffice().getId());
			}
		}
		
		/**
		 * 获取当前用户
		 * @return 取不到返回 new User()
		 */
		public static User getUser(){
			Principal principal = getPrincipal();
			if (principal!=null){
				User user = get(principal.getId());
				if (user != null){
					return user;
				}
				return new User();
			}
			// 如果没有登录，则返回实例化空的User对象。
			return new User();
		}
		/**
		 * 其他服务获取当前用户
		 * @return
		 */
		public static User getCurrentUser(){
			
			return currentUserSevice.getCurrentUser();
		}
		/**
		 * 获取当前用户角色列表
		 * @return
		 */
		public static List<Role> getRoleList(){
			@SuppressWarnings("unchecked")
			List<Role> roleList = (List<Role>)getCache(CacheDict.CACHE_ROLE_LIST);
			if (roleList == null){
				User user = getUser();
				if (user.isAdmin()){
					roleList = roleService.findAllList(new Role());
				}else{
					Role role = new Role();
					role.getSqlMap().put("dsf", DataScopeFilter.dataScopeFilter(user.getCurrentUser(), "o", "u"));
					roleList = roleService.findList(role);
				}
				putCache(CacheDict.CACHE_ROLE_LIST, roleList);
			}
			return roleList;
		}
		
		/**
		 * 获取当前用户授权菜单
		 * @return
		 */
		public static List<Menu> getMenuList(){
			@SuppressWarnings("unchecked")
			List<Menu> menuList = (List<Menu>)getCache(CacheDict.CACHE_MENU_LIST);
			if (menuList == null){
				User user = getUser();
				if (user.isAdmin()){
					menuList = menuService.findAllList(new Menu());
				}else{
					Menu m = new Menu();
					m.setUserId(user.getId());
					menuList = menuService.findByUserId(m);
				}
				putCache(CacheDict.CACHE_MENU_LIST, menuList);
			}
			return menuList;
		}
		
		/**
		 * 获取当前用户授权的区域
		 * @return
		 */
		public static List<Area> getAreaList(){
			@SuppressWarnings("unchecked")
			List<Area> areaList = (List<Area>)getCache(CacheDict.CACHE_AREA_LIST);
			if (areaList == null){
				areaList = areaService.findAllList(new Area());
				putCache(CacheDict.CACHE_AREA_LIST, areaList);
			}
			return areaList;
		}
		
		/**
		 * 获取当前用户有权限访问的部门
		 * @return
		 */
		public static List<Office> getOfficeList(){
			@SuppressWarnings("unchecked")
			List<Office> officeList = (List<Office>)getCache(CacheDict.CACHE_OFFICE_LIST);
			if (officeList == null){
				User user = getUser();
				if (user.isAdmin()){
					officeList = officeService.findAllList(new Office());
				}else{
					Office office = new Office();
					office.getSqlMap().put("dsf", DataScopeFilter.dataScopeFilter(user, "a", ""));
					officeList = officeService.findList(office);
				}
				putCache(CacheDict.CACHE_OFFICE_LIST, officeList);
			}
			return officeList;
		}

		/**
		 * 获取当前用户有权限访问的部门
		 * @return
		 */
		public static List<Office> getOfficeAllList(){
			@SuppressWarnings("unchecked")
			List<Office> officeList = (List<Office>)getCache(CacheDict.CACHE_OFFICE_ALL_LIST);
			if (officeList == null){
				officeList = officeService.findAllList(new Office());
			}
			return officeList;
		}
		
		/**
		 * 获取授权主要对象
		 */
		public static Subject getSubject(){
			return SecurityUtils.getSubject();
		}
		
		/**
		 * 获取当前登录者对象
		 */
		public static Principal getPrincipal(){
			try{
				Subject subject = SecurityUtils.getSubject();
				Principal principal = (Principal)subject.getPrincipal();
				if (principal != null){
					return principal;
				}
//				subject.logout();
			}catch (UnavailableSecurityManagerException e) {
				
			}catch (InvalidSessionException e){
				
			}
			return null;
		}
		
		public static Session getSession(){
			try{
				Subject subject = SecurityUtils.getSubject();
				Session session = subject.getSession(false);
				if (session == null){
					session = subject.getSession();
				}
				if (session != null){
					return session;
				}
//				subject.logout();
			}catch (InvalidSessionException e){
				
			}
			return null;
		}
		
		// ============== User Cache ==============
		
		public static Object getCache(String key) {
			return getCache(key, null);
		}
		
		public static Object getCache(String key, Object defaultValue) {
			//Object obj = getCacheMap().get(key);
			Object obj = getSession().getAttribute(key);
			return obj==null?defaultValue:obj;
		}

		public static void putCache(String key, Object value) {
			//getCacheMap().put(key, value);
			getSession().setAttribute(key, value);
		}

		public static void removeCache(String key) {
			//getCacheMap().remove(key);
			getSession().removeAttribute(key);
		}
		
	public static Map<String, Object> getCacheMap(){
			Principal principal = getPrincipal();
			if(principal!=null){
				return principal.getCacheMap();
			}
		return new HashMap<String, Object>();
		}
		
	}
